package gui.edt.swingutilities;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;


/*
 * To be added to google Calendar and google CODE
 */
public class FreezeEDTSwingUtilities extends JFrame implements ActionListener {
	
	private static int CPT = 0;
	private JLabel label = new JLabel();

	public FreezeEDTSwingUtilities() {
		// TODO Auto-generated constructor stub
		setLayout(new BorderLayout());
		JButton freezer = new JButton("Freeze me");
		freezer.addActionListener(this);
		add(freezer, BorderLayout.SOUTH);
		add(label, BorderLayout.NORTH);
		pack();
		setLocationRelativeTo(null);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
	}

	public void waitAWhile() {
		try {
			System.out.println("Started");
			Thread.sleep(4000);
			System.out.println("Finished");
			CPT++;
			/*
			 * As all Swing events are managed inside ONE thread (EDT), so as to
			 * respect this constraint we MUST manage all Swing Events in the
			 * EDT. As a consequence, we use the static method
			 * SwingUtilities.isEventDispatchThread() to be sure of updating the
			 * GUI from the EDT thread !!
			 */
			SwingUtilities.invokeLater(new Runnable() {

				@Override
				public void run() {
					// TODO Auto-generated method stub
					boolean answer = false;
					if (answer = SwingUtilities.isEventDispatchThread()) {
						System.out.println("In the EDT : " + answer);
						label.setText("finished from EDT " + CPT);
						pack();
						repaint();
					}
				}
			});
		} catch (InterruptedException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	}
	
	public void waitAWhile2() {
		try {
			System.out.println("Started");
			Thread.sleep(4000);
			System.out.println("Finished");
			CPT++;
			
			/*
			 * As all Swing events are managed inside ONE thread (EDT), so as to
			 * respect this constraint we MUST manage all Swing Events in the
			 * EDT. As a consequence, we use the static method
			 * SwingUtilities.isEventDispatchThread() to be sure of updating the
			 * GUI from the EDT thread !!
			 */
			final boolean answer;
			if (!(answer = SwingUtilities.isEventDispatchThread())) {
				SwingUtilities.invokeLater(new Runnable() {
					
					@Override
					public void run() {
						// TODO Auto-generated method stub
						updateText(answer);
					}
				});
			} else {
				updateText(answer);
			}
		} catch (InterruptedException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	}
	
	public void waitAWhile3() {
		System.out.println("Started");
		try {
			Thread.sleep(4000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("Finished");
		CPT++;

		Runnable work = new Runnable() {
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				updateText();
			}
		};
		
		if (SwingUtilities.isEventDispatchThread()) {
			work.run();
		} else {
			SwingUtilities.invokeLater(work);
		}
	}
	
	private void updateText() {
		label.setText("finished from EDT " + CPT);
		pack();
		repaint();
	}
	
	private void updateText(boolean answer) {
		String mess = "" + answer;
		if (!answer) {
			mess = "after a SwingUtilities.invokeLater(...) call";
		}
		System.out.println("In the EDT : " + mess);
		label.setText("finished from EDT " + CPT);
		pack();
		repaint();
	}


	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		SwingUtilities.invokeLater(new Runnable() {

			@Override
			public void run() {
				/*
				 * As the task to process is lengthy we run another thread
				 * outside the EDT !!
				 */
				new Thread(new Runnable() {

					@Override
					public void run() {
						// TODO Auto-generated method stub
						if (!SwingUtilities.isEventDispatchThread()) 
//							waitAWhile();
//							waitAWhile2();
							waitAWhile3();
					}
				}).start();
			}
		});
	}

	public static void main(String[] args) {
		/*
		 * We must run all that concerns the GUI in the EDT !!
		 */
		SwingUtilities.invokeLater(new Runnable() {
			
			@Override
			public void run() {
				FreezeEDTSwingUtilities ihm = new FreezeEDTSwingUtilities();
				ihm.setVisible(true);
			}
		});
	}
}
